/* eslint-disable react/jsx-no-target-blank */
import { FC, MouseEventHandler, ReactElement, useRef, useState } from "react";
import styled from "styled-components";
import Image from "next/image";
import { useMount } from "../../hooks";
import { getPokers } from "../../api/pokerApi";
import { getImagePath } from "../../constant/url";
import { ThemeText } from "../BUI/View/ThemeView";
import Arrow from "../BUI/Icon/Arrow";

interface RecommendProps {
  _id: string;
  title: string;
  images: string[];
  description: string;
  url: string;
}

interface IProps {}

const Recommend: FC<IProps> = (): ReactElement => {
  const [currIndex, setCurrIndex] = useState(0);
  const [toggleNext, setToggleNext] = useState(false);
  const [recommendList, setRecommendList] = useState([]);
  const starPage = useRef({ X: 0, Y: 0 });
  const dragRef = useRef<HTMLDivElement | null>(null);

  useMount(() => {
    getPokers().then(res => {
      setRecommendList(res.data);
    });
  });

  const setElementTopAndLeft = (top: number, left: number): void => {
    if (dragRef.current) {
      dragRef.current.style["top"] = top + "px";
      dragRef.current.style["left"] = left + "px";
    }
  };
  const recommendDate = (index: number) => {
    const validIndex = index < recommendList.length ? index : 0;
    return recommendList[validIndex];
  };

  const handleSetSourceIndex = () => {
    const { length } = recommendList;
    setCurrIndex(prev => (prev + 1 < length ? prev + 1 : 0));
  };

  const handleMouseMove: EventListenerOrEventListenerObject = ({
    pageX,
    pageY,
  }: any) => {
    const { X, Y } = starPage.current;
    setElementTopAndLeft(pageY - Y, pageX - X);
  };

  const handleMouseUp: EventListenerOrEventListenerObject = ({
    pageX,
  }: any) => {
    if (!dragRef.current) return;
    // setStarDrag(false);
    const { X } = starPage.current;
    if (pageX - X > 400) {
      //切换下一张
      dragRef.current.setAttribute("data-back", "true");
      setElementTopAndLeft(-1000, X);
      setToggleNext(true);
      setTimeout(() => {
        dragRef.current && dragRef.current.setAttribute("data-back", "");
        setElementTopAndLeft(0, 0);
        handleSetSourceIndex();
        setToggleNext(false);
      }, 400);
    } else {
      dragRef.current.setAttribute("data-back", "true");
      setElementTopAndLeft(0, 0);
    }

    dragRef.current.setAttribute("data-star-drag", "false");
    document.removeEventListener("mousemove", handleMouseMove);
    document.removeEventListener("mouseup", handleMouseUp);
    document.removeEventListener("mouseleave", handleMouseUp);
  };

  const handleMouseDown: MouseEventHandler<HTMLDivElement> = ({
    target,
    currentTarget,
    pageX,
    pageY,
  }: any) => {
    if (target.getAttribute("data-recommend")) {
      currentTarget.setAttribute("data-back", "");
      currentTarget.setAttribute("data-star-drag", "true");
      starPage.current = { X: pageX, Y: pageY };
      dragRef.current = currentTarget;
      document.addEventListener("mousemove", handleMouseMove);
      document.addEventListener("mouseup", handleMouseUp);
      document.addEventListener("mouseleave", handleMouseUp);
    }
  };

  return (
    <Container>
      <RecommendItem
        recommend={recommendDate(currIndex)}
        position={2}
        onMouseDown={handleMouseDown}
      />
      <RecommendItem
        recommend={recommendDate(currIndex + 1)}
        position={1}
        toggleNext={toggleNext}
      />
      <RecommendItem position={0} toggleNext={toggleNext} />
      <RecommendItem position={-1} toggleNext={toggleNext} />
      <RecommendItem position={-2} toggleNext={toggleNext} />
      {/* <Item deg={toggleNext ? -10 : 0} index={-3} /> */}
    </Container>
  );
};

export default Recommend;

const Container = styled.div`
  margin-top: 20px;
  margin-left: 20px;
  width: 30rem;
  height: 30rem;
  position: relative;
`;

const Item = styled.div.attrs({ "data-recommend": "recommend" })<{
  deg?: number;
  index?: number;
}>`
  width: 20rem;
  height: 30rem;
  background-color: ${props => props.theme.bg};
  border-radius: 10px;
  position: absolute;
  overflow: hidden;
  transform: ${props => `rotate(${props.deg}deg)`};
  transform-origin: bottom;
  z-index: ${props => props.index};
  user-select: none;
  box-shadow: 0 0 0px 1px ${props => props.theme.shadow};
  padding: 2.5rem;
  transition: transform 0.4s ease-in;
  cursor: grab;
  ${ThemeText};
  & > div {
    cursor: default;
  }
  &[data-back="true"] {
    transition-property: left, top, transform;
    transition-duration: 0.3s;
    transition-timing-function: ease-out;
  }
  &[data-back="false"] {
    transition: none;
  }
  &[data-star-drag="true"] {
    z-index: ${props => props.theme.index.max};
    cursor: grabbing;
  }
`;

interface RecommendItemProps {
  recommend?: RecommendProps;
  position: number;
  toggleNext?: boolean;
  onMouseDown?: MouseEventHandler<HTMLDivElement>;
  onMouseUp?: MouseEventHandler<HTMLDivElement>;
}

const RecommendItem: FC<RecommendItemProps> = ({
  recommend,
  position,
  toggleNext,
  onMouseDown,
  onMouseUp,
}) => {
  const props = {
    deg: toggleNext ? (position + 1) * 5 : position * 5,
    index: position,
    onMouseDown,
    onMouseUp,
  };
  if (recommend == undefined) return <Item {...props} />;

  const { title, images, description, url } = recommend;
  return (
    <Item {...props}>
      <ImageWrap>
        <Image src={`${getImagePath}${images[0]}`} alt={title} layout="fill" />
      </ImageWrap>
      <RecommendContent>
        <span>{title}</span>
        <p>{description}</p>
        <a target="_blank" href={url}>
          去看看
        </a>
      </RecommendContent>
    </Item>
  );
};

const ImageWrap = styled.div`
  width: 15rem;
  height: 16rem;
  position: relative;
`;

const RecommendContent = styled.div`
  display: flex;
  height: 9rem;
  flex-direction: column;
  padding-left: 1rem;

  span {
    font-weight: bold;
    letter-spacing: 1px;
    position: relative;
    padding-top: 0.6rem;

    &::after {
      content: "";
      position: absolute;
      width: calc(100% - 1rem);
      top: 0.3rem;
      left: 0;
      height: 0.1rem;
      border-radius: 1px;
      background: ${props => props.theme.shadow};
    }
  }
  p {
    color: ${props => props.theme.thinText};
    font-size: 0.9rem;
  }
  a {
    text-decoration: none;
    ${Arrow};
  }
`;
